package com.scalar.chiptrack.operations.bins.actions;

import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.db.DBXException;
import com.scalar.chiptrack.operations.bins.forms.AssemblyBinForm;
import com.scalar.chiptrack.operations.bins.dao.AssemblyBinDAO;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.process.BinSetup;
import com.scalar.chiptrack.operations.release.ReleaseHelper;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.commons.Constants;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.users.Functionality;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;

public class AssemblyBinSetupAction extends ChipTrackAction{

    public static final String ACTION_NAME = "/assemblyBinSetup.do";

    public ActionForward execute( ActionMapping mapping,
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response ) throws Exception {

        AssemblyBinForm assemblyFormBin = ( AssemblyBinForm ) form;
        HttpSession session = request.getSession();
        User user = ( User ) session.getAttribute( SessionKeys.USER_KEY );

        String  action      = request.getParameter("action");
        String  screenType  = request.getParameter("screenType");
        HashMap info   = new HashMap();
        HashMap errors = new HashMap();
        ArrayList assemblyProductList = new ArrayList();
        ArrayList binInformationList = new ArrayList();
        ArrayList binInformationListCopy = new ArrayList();

        if ( user == null )
        {
            session.setAttribute( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME + "?"+ request.getQueryString() );
            return mapping.findForward("login");
        }
        else
        {
            //screenType is baseProductBins -> MRB Bin Setup, otherwise Assembly Bin Setup.
            if( "baseProductBins".equalsIgnoreCase( screenType ) )
            {

                if ( user.isActionAllowed ( Functionality.MRB_BIN_SETUP, User.USER_ACTION_MODIFY ) )
                {
                    request.setAttribute ( "showMessage", "FALSE" );
                }
                else
                {
                    request.setAttribute ( "showMessage", "TRUE" );
                }
            }
            else
            {
                if ( user.isActionAllowed ( Functionality.ASSEMBLY_BIN_SETUP, User.USER_ACTION_MODIFY ) )
                {
                    request.setAttribute ( "showMessage", "FALSE" );
                }
                else
                {
                    request.setAttribute ( "showMessage", "TRUE" );
                }
            }
        }

        request.setAttribute( SessionKeys.INFO_MESSAGES, info );
        request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );

        if( action == null )
        {
            session.setAttribute( "BaseProducts" , AssemblyBinDAO.loadAllChipsBaseProducts() );
        }

        if( "baseProductBins".equalsIgnoreCase( screenType ) )
        {
            if( "save".equalsIgnoreCase( action )  )
            {
                DBTransaction dbTransaction = null;
                boolean success = false;

                try
                {
                    dbTransaction = DBTransaction.getInstance();
                    if( dbTransaction != null )
                    {
                        dbTransaction.begin();
                    }
                    AssemblyBinDAO.saveBaseProductBinDetails( dbTransaction, assemblyFormBin );
                    success = true;
                    info.put ("MRB Bin Details have been saved successfully", null);
                }
                catch( Exception e )
                {
                    e.printStackTrace();
                    errors.put ("Could not load MRB Bin Details into Data Base", null);
                }
                finally
                {
                    try
                    {
                        if ( success == true )
                        {
                            dbTransaction.commit();
                        }
                        else
                        {
                            dbTransaction.rollback();
                        }
                    }
                    catch ( DBXException e ){ e.printStackTrace(); }
                }
                binInformationList = AssemblyBinDAO.loadBaseProductBinInformation( assemblyFormBin.getBaseProductId() );
            }

            try
            {
                if( "loadBinsInformation".equalsIgnoreCase( action )  )
                {
                    binInformationList = AssemblyBinDAO.loadBaseProductBinInformation( assemblyFormBin.getBaseProductId() );
                }
                assemblyFormBin.setBinInformationList( binInformationList );
            }
            catch( Exception e )
            {
                e.printStackTrace();
                info.put ("Could not load MRB Bin Details","");
            }
            return mapping.findForward("baseProductBinsSetup");
        }
        else
        {
            if( "save".equalsIgnoreCase( action )  )
            {
                DBTransaction dbTransaction = null;
                boolean success = false;

                try
                {
                    dbTransaction = DBTransaction.getInstance();
                    if( dbTransaction != null )
                    {
                        dbTransaction.begin();
                    }
                    binInformationList = assemblyFormBin.getBinInformationList();
                    binInformationListCopy = assemblyFormBin.getBinInformationListCopy();
                    AssemblyBinDAO.saveBinDetails( dbTransaction, assemblyFormBin );


                    success = true;
                }
                catch( Exception e )
                {
                    e.printStackTrace();
                    errors.put ("Could not load Assembly Bin Details into Data Base", null);
                }
                finally
                {
                    try
                    {
                        if ( success == true )
                        {
                            dbTransaction.commit();
                            info.put ("Assembly Bin Details have been saved successfully", null);                            
                        }
                        else
                        {
                            dbTransaction.rollback();
                        }
                    }
                    catch ( DBXException e ){ e.printStackTrace(); }
                }

                if ( success )
                {
                    if( binInformationList != null && binInformationListCopy != null && binInformationList.size() > 0 && binInformationListCopy.size() > 0 && binInformationList.size() == binInformationListCopy.size() )
                    {
                        boolean assemblyBinSetupModified = false;
                        StringBuffer binsInitiallySelected = new StringBuffer();
                        StringBuffer binsNowSelected = new StringBuffer();
                        for( int i = 0; i < binInformationList.size(); i++ )
                        {
                            BinSetup binInfo = (BinSetup) binInformationList.get( i );
                            BinSetup binInfoCopy = (BinSetup) binInformationListCopy.get( i );
                            if( binInfoCopy.isSelectedBin())
                            {
                                if( binsInitiallySelected != null && binsInitiallySelected.length() > 0 )
                                {
                                    binsInitiallySelected.append(", ");
                                }
                                binsInitiallySelected.append( binInfoCopy.getBinNo());
                            }
                            if( binInfo.isSelectedBin())
                            {
                                if( binsNowSelected != null && binsNowSelected.length() > 0 )
                                {
                                    binsNowSelected.append(", ");
                                }
                                binsNowSelected.append( binInfo.getBinNo());
                            }
                            if( binInfo.isSelectedBin() != binInfoCopy.isSelectedBin() )
                            {
                                assemblyBinSetupModified = true;
                            }
                        }
                        if( assemblyBinSetupModified )
                        {
                            String assemblyPartNumber = ProductDao.getDeviceName( assemblyFormBin.getAssemblyProccessStepId() );
                            String subject = "Assembly Bin Setup modified for Assembly Part Number "+assemblyPartNumber;
                            StringBuffer message = new StringBuffer("Assembly Bin Setup is modified for Assembly Part Number "+assemblyPartNumber+" from "+binsInitiallySelected.toString()+" to "+binsNowSelected.toString()+".<br><br>");
                            try
                            {
                                //ReleaseHelper.notifyAllReceipients( user, subject, message.toString(), Constants.NOTIFICATION_EMAIL_TYPE_FOR_LOT_FLOW );
                            }
                            catch ( Exception e )
                            {
                                errors.put ( "Could not send mail notification", null );
                            }
                        }
                    }
                }

                assemblyProductList = AssemblyBinDAO.loadAllAssemblyProductsByBaseProductId( assemblyFormBin.getBaseProductId() );
                binInformationList = AssemblyBinDAO.loadBinInformation( assemblyFormBin.getAssemblyProccessStepId() );
                assemblyFormBin.setBinInformationListCopy( getCopyOfBinInformationList(binInformationList) );
            }

            try
            {
                if( "loadAssemblyProducts".equalsIgnoreCase( action ) || "loadBinsInformation".equalsIgnoreCase( action )  )
                {
                    assemblyProductList = AssemblyBinDAO.loadAllAssemblyProductsByBaseProductId( assemblyFormBin.getBaseProductId() );
                }
                request.setAttribute( "AssemblyProducts" , assemblyProductList );

                if( "loadBinsInformation".equalsIgnoreCase( action )  )
                {
                    binInformationList = AssemblyBinDAO.loadBinInformation( assemblyFormBin.getAssemblyProccessStepId() );
                    assemblyFormBin.setBinInformationListCopy( getCopyOfBinInformationList( binInformationList)  );
                }
                assemblyFormBin.setBinInformationList( binInformationList );
            }
            catch( Exception e )
            {
                e.printStackTrace();
                info.put ("Could not load Assembly Bin Details","");
            }
            return mapping.findForward("success");
        }
    }

    private ArrayList getCopyOfBinInformationList( ArrayList binInformationList )
    {
        ArrayList binInformationListCopy = new ArrayList();
        if( binInformationList != null && binInformationList.size() > 0)
        {
            Iterator binInformationListIterator = binInformationList.iterator();
            while( binInformationListIterator.hasNext())
            {
                BinSetup binInfo = (BinSetup) binInformationListIterator.next();
                BinSetup binInfoCopy = new BinSetup();
                binInfoCopy.setBinNo( binInfo.getBinNo() ) ;
                binInfoCopy.setSelectedBin( binInfo.isSelectedBin() );
                binInformationListCopy.add( binInfoCopy );
                binInfoCopy = null;
            }
        }
        return binInformationListCopy;
    }
}
